<?php
/**
 * 分类控制器
 */

namespace app\admin\controller;

use app\common\model\Brand;
use app\common\model\Cate;
use app\common\model\Spec;
use app\common\model\Type;
use app\common\model\TypeLog;
use app\common\validate\TypeValidate;
use Exception;
use PhpOffice\PhpSpreadsheet\IOFactory;
use think\db\Query;
use think\facade\Config;
use think\facade\Db;
use think\facade\Filesystem;
use think\Request;
use think\response\Json;

class TypeController extends AdminBaseController {

	/**
	 * 列表
	 * @param Request $request
	 * @param Type $model
	 * @return string
	 * @throws Exception
	 */
	public function index(Request $request, Type $model): string {
		$param = $request->param();
		//$param['tag'] = 1;
		$this->assign('data', $this->getMenuTree($model, $param));
		$this->assign($request->get());
		return $this->fetch();
	}
	public function search(Request $request, Type $model): string {
		$param = $request->param();
		$data = $model->scope('where', $param)
			->paginate([
				'list_rows' => $this->admin['admin_list_rows'],
				'var_page' => 'page',
				'query' => $request->get(),
			]);
		// 关键词，排序等赋值
		$this->assign($request->get());

		$this->assign([
			'data' => $data,
			'page' => $data->render(),
			'total' => $data->total(),
		]);
		return $this->fetch();
	}
	/**
	 * 添加
	 * @param Request $request
	 * @param Type $model
	 * @param TypeValidate $validate
	 * @return string|Json
	 * @throws Exception
	 */
	public function add(Request $request, Type $model, TypeValidate $validate) {
		if ($request->isPost()) {
			$param = $request->param();
			$validate_result = $validate->scene('admin_add')->check($param);
			if (!$validate_result) {
				return admin_error($validate->getError());
			}
			$parent = Type::find($param['parent_id']);
			if (isset($parent['parent_id']) && $parent['parent_id'] != 0) {
				return admin_error('最多2级分类');
			}
			$result = $model::create($param);

			$url = URL_BACK;
			if (isset($param['_create']) && (int) $param['_create'] === 1) {
				$url = URL_RELOAD;
			}
			return $result ? admin_success('添加成功', [], $url) : admin_error();
		}
		$this->assign([
			'parent_list' => $this->getSelectList($model),
			'cate_list' => Cate::where('status', 1)->select(),
			'spec_list' => Spec::select(),
			'brand_list' => Brand::select(),
		]);

		return $this->fetch();
	}

	/**
	 * 修改
	 * @param $id
	 * @param Request $request
	 * @param Type $model
	 * @param TypeValidate $validate
	 * @return string|Json
	 * @throws Exception
	 */
	public function edit($id, Request $request, Type $model, TypeValidate $validate) {
		$data = $model->findOrEmpty($id);
		if ($request->isPost()) {
			$param = $request->param();
			$check = $validate->scene('admin_edit')->check($param);
			if (!$check) {
				return admin_error($validate->getError());
			}
			$parent = Type::find($param['parent_id']);
			if (isset($parent['parent_id']) && $parent['parent_id'] != 0) {
				return admin_error('最多2级分类');
			}
			$result = $data->save($param);

			return $result ? admin_success('修改成功', [], URL_BACK) : admin_error('修改失败');
		}

		$this->assign([
			'data' => $data,
			'parent_list' => $this->getSelectList($model, $data->parent_id),
			'cate_list' => Cate::where('status', 1)->select(),
			'spec_list' => Spec::select(),
			'brand_list' => Brand::select(),
		]);

		return $this->fetch('add');
	}
	public function info($id, Request $request) {
		$param = $request->param();
		$this->assign($request->get());
		if (isset($param['create_time']) && !empty($param['create_time'])) {
			$time_range = explode(' - ', $param['create_time']);
			[$start_time, $end_time] = $time_range;

			$start_time = strtotime($start_time);
			if (strlen($end_time) === 10) {
				$end_time .= ' 23:59:59';
			}
			$end_time = strtotime($end_time);
			$price = TypeLog::where('type_id', $id)->whereBetweenTime('create_time', $start_time, $end_time)->order('create_time', 'asc')->column('price');
			$time = TypeLog::where('type_id', $id)->whereBetweenTime('create_time', $start_time, $end_time)->order('create_time', 'asc')->column('create_time');
			foreach ($time as $key => $value) {
				$time[$key] = date('Y-m-d', $value);
			}
		} else {
			$price = TypeLog::where('type_id', $id)->whereWeek('create_time')->order('create_time', 'asc')->column('price');
			$time = TypeLog::where('type_id', $id)->whereWeek('create_time')->order('create_time', 'asc')->column('create_time');
			foreach ($time as $key => $value) {
				$time[$key] = date('Y-m-d', $value);
			}
		}

		$this->assign([
			'price' => json_encode($price),
			'time' => json_encode($time),
		]);
		return $this->fetch();
	}
	/**
	 * 删除
	 * @param mixed $id
	 * @param Type $model
	 * @return Json
	 */
	public function del($id, Type $model): Json {
		return admin_error('存在关联数据,请删除关联数据再删除');
		$check = $model->inNoDeletionIds($id);
		if (false !== $check) {
			return admin_error('ID为' . $check . '的数据不能被删除');
		}

		$result = $model::destroy(static function ($query) use ($id) {
			/** @var Query $query */
			$query->whereIn('id', $id);
		});

		return $result ? admin_success('删除成功', [], URL_RELOAD) : admin_error('删除失败');
	}

	protected function getMenuTree(Type $model, $param): string {
		// 查询所有菜单并以树的形式显示
		$result = $model->scope('where', $param)->order('id', 'asc')
			->column('*', 'id');

		foreach ($result as $n => $r) {
			$result[$n]['level'] = $this->getLevel($r['id'], $result);
			$result[$n]['parent_id_node'] = $r['parent_id'] ? ' class="child-of-node-' . $r['parent_id'] . '"' : '';

			$result[$n]['str_manage'] = '<a href="' . url('edit', ['id' => $r['id']]) . '" class="btn btn-primary btn-xs" title="修改" data-toggle="tooltip"><i class="fas fa-pen"></i>修改</a> ';
			$result[$n]['str_manage'] .= '<button class="btn btn-danger btn-xs AjaxButton" data-id="' . $r['id'] . '" data-url="del.html"  data-confirm-title="删除确认" data-confirm-content=\'您确定要删除ID为 <span class="text-red"> ' . $r['id'] . ' </span> 的数据吗\'  data-toggle="tooltip" title="删除"><i class="fas fa-trash"></i>删除</button>  ';
			if ($r['parent_id'] != 0) {
				$result[$n]['str_manage'] .= '<a href="' . url('info', ['id' => $r['id']]) . '" class="btn btn-primary btn-xs" title="走势" data-toggle="tooltip"><i class="fas fa-chart-line"></i>走势</a> ';
			}

		}

		$str = "<tr id='node-\$id' data-level='\$level' \$parent_id_node><td><input type='checkbox' onclick='checkThis(this)'
                     name='dataCheckbox' data-id='\$id\' class='checkbox dataListCheck' value='\$id' placeholder='选择/取消'>
                    </td><td>\$id</td><td>\$spacer\$name</td>
                    <td>\$parent_id</td>
                    <td class='td-do'>\$str_manage</td></tr>";

		$this->initTree($result);
		return $this->getTree(0, $str);
	}
	public function import(Request $request): Json {

		$param = $request->param();

		$field_list = ['parent', 'name'];
		$result = $this->importData('file', 'type', $field_list);

		return true === $result ? admin_success('操作成功', [], URL_RELOAD) : admin_error($result);
	}
	public function importData(string $name, string $table, array $field_list, int $limit = 100, bool $del = true) {
		$config = config('filesystem.disks.admin_import');
		$file = request()->file($name);
		try {
			validate($config['validate'])->check([$name => $file]);

			$file_name = Filesystem::disk('admin_import')->putFile($table, $file);
			if ($file_name === false) {
				return '上传文文件失败';
			}
		} catch (ValidateException $e) {
			return '文件验证失败，信息：' . $e->getMessage();
		}

		$path = $config['root'] . '/' . $file_name;

		$spreadsheet = IOFactory::load($path);
		$excel_array = $spreadsheet->getActiveSheet()->toArray();
		array_shift($excel_array);
		if (empty($excel_array)) {
			return '导入文件数据为空';
		}

		Db::startTrans();
		try {
			$time = time();
			$all_data = [];
			foreach ($excel_array as $key => $value) {
				$data = [];
				foreach ($field_list as $field_key => $field_value) {
					if (!isset($value[$field_key])) {
						// throw new RuntimeException('第 ' . ($key + 2) . ' 行第 ' . $field_key . ' 列缺少数据');
					}
					$data[$field_value] = $value[$field_key];
				}
				// 有创建时间和更新时间的处理
				$data['create_time'] = $time;
				$data['update_time'] = $time;
				$data['tag'] = 0;
				$cate = Cate::where('name', $data['parent'])->findOrEmpty();
				if ($cate->isEmpty()) {
					$cate = Cate::create(['name' => $data['parent'], 'status' => 1]);
					$data['cate_id'] = $cate->id;
				} else {
					$data['cate_id'] = $cate->id;
				}
				$parent = Type::where('name', $data['parent'])->findOrEmpty();
				if ($parent->isEmpty()) {
					$parent = Type::create(['parent_id' => 0, 'cate_id' => $data['cate_id'], 'name' => $data['parent']]);
					$data['parent_id'] = $parent->id;
				} else {
					$data['parent_id'] = $parent->id;
				}
				// $spec = Spec::where('name', $data['spec'])->findOrEmpty();
				// if (!$spec->isEmpty()) {
				// 	$data['spec_id'] = $spec['id'];
				// }
				// $brand = Brand::where('name', $data['brand'])->findOrEmpty();
				// if (!$spec->isEmpty()) {
				// 	$data['brand_id'] = $brand['id'];
				// }
				unset($data['parent'], $data['spec'], $data['brand']);
				$all_data[] = $data;

			}

			Db::name($table)
				->limit($limit)
				->insertAll($all_data);
			Db::commit();
			$result = true;
		} catch (Exception $exception) {
			Db::rollback();
			$result = '导入失败，信息：' . $exception->getMessage();
		}
		if ($del) {
			unlink($path);
		}
		return $result;
	}
}
